perm filename MIXER.SAI[T,LCS] blob
sn#010300 filedate 1972-10-16 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00005 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00002 00002 BEGIN "MIXER"
00005 00003 PROCEDURE NEXT_OUTPUT_FILE
00009 00004 BEGIN "MAIN LOOP"
00013 00005 Do actual mixing
00015 ENDMK
⊗;
BEGIN "MIXER"
COMMENT A program to edit sounds in digital form.
Thanks go to Loren Rush and John Grey for there
inspiration and suggestion;
REQUIRE "⊂⊃⊂⊃" DELIMITERS;
DEFINE BYTES_PER_WORD=2;
DEFINE DSK_BLOCK_SIZE='200;
DEFINE MAX_INPUT=10;
DEFINE BUF_SIZE=DSK_BLOCK_SIZE;
DEFINE OUT_SIZE=DSK_BLOCK_SIZE;
DEFINE OUT_BLOCK_MAX=14*10;
DEFINE MAX_CON='377777;
INTEGER NUM_INPUTS,JUNK;
INTEGER OUT_BLOCK,OUT_EOF,OUT_BLOCK_COUNT,OUT_COUNT,OUT_BYTE_POINTER,MAX_OUT;
BOOLEAN DONE_FLAG;
STRING OUT_FILE;
REAL ARRAY GAIN[1:MAX_INPUT];
COMMENT GAIN is what the samples are multiplied
after begin normalized;
INTEGER ARRAY MAX_AMP[1:MAX_INPUT];
COMMENT MAX_AMP is the maximum amplitute, used to normalize
the inputs;
REAL ARRAY MULFACTOR[1:MAX_INPUT];
COMMENT MULFACTOR=GAIN/MAX_AMPLITUDE;
INTEGER ARRAY INTMULTIPLIER[1:MAX_INPUT];
COMMENT Normalized integer multipier for samples;
STRING ARRAY IN_FILE[1:MAX_INPUT];
COMMENT INTEGER ARRAY USETI_POINTER[1:MAX_INPUT];
COMMENT Indicates what's in core;
INTEGER ARRAY BIGBUF[1:MAX_INPUT,1:BUF_SIZE];
COMMENT Buffers for each input channel;
INTEGER ARRAY OUT_BUF[1:OUT_SIZE];
INTEGER ARRAY FIRST_BLOCK[1:MAX_INPUT];
COMMENT First extension or block to use for each
channel;
INTEGER ARRAY BLOCK[1:MAX_INPUT];
COMMENT Block currently being read from;
INTEGER ARRAY LAST_BLOCK[1:MAX_INPUT];
COMMENT Last extension or block to use for each
channel;
INTEGER ARRAY EOF[1:MAX_INPUT];
COMMENT End of file status for each channel;
SAFE INTEGER ARRAY BYTE_COUNT[1:MAX_INPUT];
SAFE INTEGER ARRAY BYTE_POINTER[1:MAX_INPUT];
DEFINE COMMA_TABLE=18;
PROCEDURE NEXT_OUTPUT_FILE;
BEGIN "NEXT_OUTPUT_FILE"
DEFINE CHANNEL=0;
STRING FILENAME;
ENTER(CHANNEL,FILENAME←OUT_FILE&"."&CVS(OUT_BLOCK←OUT_BLOCK+1),OUT_EOF);
IF OUT_EOF THEN
USERERR(0,0,"can't write "&FILENAME);
OUTSTR("Writing "&FILENAME&"
");
OUT_BLOCK_COUNT←0;
OUT_COUNT←BYTES_PER_WORD*BUF_SIZE;
OUT_BYTE_POINTER←POINT(18,OUT_BUF[1],-1);
END "NEXT_OUTPUT_FILE";
PROCEDURE NEXT_BLOCK(INTEGER CHANNEL);
IF CHANNEL≥1 THEN
IF BLOCK[CHANNEL]≥LAST_BLOCK[CHANNEL] THEN BEGIN;
OUTSTR(IN_FILE[CHANNEL]&" finished
");
BYTE_COUNT[CHANNEL]←-1;
END
ELSE BEGIN "DO_INPUT";
OUTCHR("↓");
IF ¬EOF[CHANNEL] THEN ARRYIN(CHANNEL,BIGBUF[CHANNEL,1],BUF_SIZE);
IF EOF[CHANNEL] THEN BEGIN "NEXT_INPUT_FILE"
STRING FILENAME;
LOOKUP(CHANNEL,FILENAME←IN_FILE[CHANNEL]&"."&CVS(BLOCK[CHANNEL]←
BLOCK[CHANNEL]+1),EOF[CHANNEL]);
IF EOF[CHANNEL] THEN BEGIN;
OUTSTR(FILENAME&" not found, Set terminated
");
BYTE_COUNT[CHANNEL]←-1;
END
ELSE BEGIN;
OUTSTR("Reading "&FILENAME&"
");
ARRYIN(CHANNEL,BIGBUF[CHANNEL,1],BUF_SIZE);
IF EOF[CHANNEL] THEN BEGIN
OUTSTR(FILENAME&" empty, Set terminated
");
BYTE_COUNT[CHANNEL]←-1;
END
ELSE BYTE_COUNT[CHANNEL]←BYTES_PER_WORD*BUF_SIZE;
END;
END "NEXT_INPUT_FILE"
ELSE BYTE_COUNT[CHANNEL]←BYTES_PER_WORD*BUF_SIZE;
BYTE_POINTER[CHANNEL]←POINT(18,BIGBUF[CHANNEL,1],-1);
END "DO_INPUT"
ELSE BEGIN "DO_OUTPUT"
INTEGER I;
OUTCHR("↑");
DONE_FLAG←TRUE;
FOR I←1 STEP 1 UNTIL NUM_INPUTS DO
IF BYTE_COUNT[I]≥0 THEN DONE_FLAG←FALSE;
IF OUT_BLOCK_COUNT=OUT_BLOCK_MAX OR DONE_FLAG THEN QUICK_CODE
MOVE '13,MAX_OUT;
EXCH '13,@OUT_BYTE_POINTER;
MOVEM '13,I;
END;
ARRYOUT(CHANNEL,OUT_BUF[1],OUT_SIZE);
OUT_COUNT←BYTES_PER_WORD*BUF_SIZE;
OUT_BYTE_POINTER←POINT(18,OUT_BUF[1],-1);
IF OUT_BLOCK_COUNT=OUT_BLOCK_MAX AND ¬DONE_FLAG THEN BEGIN
OUT_BUF[1]←I;
OUT_COUNT←OUT_COUNT+BYTES_PER_WORD;
OUT_BYTE_POINTER←OUT_BYTE_POINTER+1;
END;
IF OUT_BLOCK_COUNT≥OUT_BLOCK_MAX AND ¬DONE_FLAG THEN
NEXT_OUTPUT_FILE;
OUT_BLOCK_COUNT←OUT_BLOCK_COUNT+1;
END "DO_OUTPUT";
BEGIN "MAIN LOOP"
INTEGER I;
REAL GAIN_SUM,MUL_SUM;
STRING FILENAME;
DONE_FLAG←FALSE;
SETBREAK(COMMA_TABLE,","&'15," "&'12,"IOSN");
OUTSTR("*** Digital Music Mixer ***
July 1972
");
OUTSTR("Number of inputs=");
NUM_INPUTS←CVD(INCHWL);
IF NUM_INPUTS>MAX_INPUT THEN
USERERR(0,0,"TOO MANY INPUTS");
OUTSTR("File name, starting extension or block, ending extension or block:
");
FOR I←1 STEP 1 UNTIL NUM_INPUTS DO BEGIN STRING FOO;
INTEGER ARRAY INFOTAB[1:6];
OUTSTR("#"&CVS(I)&" ");
IN_FILE[I]←TTYINL(COMMA_TABLE,JUNK);
FIRST_BLOCK[I]←CVD(TTYINS(COMMA_TABLE,JUNK));
LAST_BLOCK[I]←CVD(INSTR('15));
OPEN(I,"DSK",'17,0,0,JUNK,JUNK,EOF[I]←0);
LOOKUP(I,FOO←IN_FILE[I]&"."&CVS(LAST_BLOCK[I]),EOF[I]);
IF EOF[I] THEN USERERR(0,0,"CAN'T GET FILE: "&FOO);
FILEINFO(INFOTAB);
USETI(I,('1000000-INFOTAB[4])%('1000000*DSK_BLOCK_SIZE));
ARRYIN(I,BIGBUF[I,1],DSK_BLOCK_SIZE);
OUTSTR("Maximum amplitude="&CVS(MAX_AMP[I]←BIGBUF[I,DSK_BLOCK_SIZE])&"
");
CLOSE(I);
EOF[I]←TRUE;
BYTE_COUNT[I]←0;
END;
OUTSTR("
Set gain for each input:
");
FOR I←1 STEP 1 UNTIL NUM_INPUTS DO BEGIN STRING FOO;
OUTSTR(CVS(I)&" "&IN_FILE[I]&" ");
GAIN[I]←REALSCAN(FOO←INCHWL,'15);
MULFACTOR[I]←GAIN[I]/MAX_AMP[I];
BLOCK[I]←FIRST_BLOCK[I]-1;
BYTE_COUNT[I]←0;
END;
OUTSTR("
Output file, Starting extension or block: ");
OUT_FILE←TTYINL(COMMA_TABLE,JUNK);
OUT_BLOCK←CVD(INSTR('15))-1;
OPEN(0,"DSK",'17,0,0,JUNK,JUNK,OUT_EOF←0);
GAIN_SUM←0;
FOR I←1 STEP 1 UNTIL NUM_INPUTS DO BEGIN
MUL_SUM←MUL_SUM+MULFACTOR[I]*MAX_AMP[I];
GAIN_SUM←GAIN_SUM+MULFACTOR[I];
END;
OUTSTR("Maximum output (default="&CVS(MAX_CON)&") ");
IF (MAX_OUT←CVD(INCHWL))≤0 THEN
MAX_OUT←MAX_CON
ELSE IF MAX_OUT>'377777 THEN USERERR(0,0,"Maximum output limited to "&
CVS(MAX_CON));
OUTSTR("
Multipliers for each input:
File Max. Amp % Gain Normalized gain
");
FOR I←1 STEP 1 UNTIL NUM_INPUTS DO
OUTSTR(CVS(I)&" "&IN_FILE[I]&" "&CVS(MAX_AMP[I])&" "&
CVG(MULFACTOR[I]/GAIN_SUM)&" "&CVG(MULFACTOR[I]/MUL_SUM*MAX_OUT)&"
");
OUTSTR("
");
FOR I←1 STEP 1 UNTIL NUM_INPUTS DO
INTMULTIPLIER[I]←MULFACTOR[I]/MUL_SUM*MAX_OUT*'400000;
MAX_OUT←0;
NEXT_OUTPUT_FILE;
COMMENT Do actual mixing;
DO BEGIN INTEGER I,T;
T←0;
FOR I←1 STEP 1 UNTIL NUM_INPUTS DO
IF BYTE_COUNT[I]≥0 THEN BEGIN;
IF (BYTE_COUNT[I]←BYTE_COUNT[I]-1)≤0
THEN NEXT_BLOCK(I);
COMMENT T←T+ILDB(BYTE_POINTER[I])*MULFACTOR[I];
QUICK_CODE
MOVE '13,BYTE_POINTER;
ADD '13,I;
ILDB '13,-1('13);
HRLZ '13,'13; COMMENT Won't work for 12 bit!;
MOVE '14,INTMULTIPLIER;
ADD '14,I;
MUL '13,-1('14);
ADDM '13,T;
END;
END;
IDPB(T,OUT_BYTE_POINTER);
IF ABS(T)>MAX_OUT THEN MAX_OUT←ABS(T);
IF (OUT_COUNT←OUT_COUNT-1)≤0 THEN NEXT_BLOCK(0);
END UNTIL DONE_FLAG;
CLOSE(0);
OUTSTR("
Output Maximum amplitude="&CVS(MAX_OUT));
OUTSTR("
");
END "MAIN LOOP";
END "MIXER";